package org.jeecg.modules.xmss.util;


import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.*;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.Arrays;
import java.util.logging.Logger;

import org.apache.http.entity.ContentType;
import org.mybatis.logging.LoggerFactory;
import org.springframework.mock.web.MockMultipartFile;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import com.alibaba.fastjson.util.Base64;

import javax.imageio.ImageIO;
import javax.imageio.stream.FileImageOutputStream;

/**
 * @Function : 图片处理帮助类 - 把URL里的图片导入到本地 - 将IMG的SRC地址转为File - base64编码图片转 MultipartFile
 * @Author & @Date : lynn_ - 2018年06月15日
 */
@Service("webFileUtils")
public class WebFileUtils {

    /**
     * 临时文件位置
     */
    private static String tempFilePath = "";

    /**
     * 根据url拿取file
     *
     * @param url
     * @param suffix - 文件后缀名
     */
    public static File createFileByUrl(String url, String suffix) {
        byte[] byteFile = getImageFromNetByUrl(url);
        if (byteFile != null) {
            File file = getFileFromBytes(byteFile, suffix);
            return file;
        } else {
            System.out.println("生成文件失败！");
            return null;
        }
    }

    /**
     * @Function: 创建临时文件
     * @param byteFile
     * @param suffix
     */
    private static File getFileFromBytes(byte[] byteFile, String suffix) {
        BufferedOutputStream stream = null;
        File file = null;
        try {
            //注意这里的临时文件 需要自行删除
            file = File.createTempFile("pattern", "." + suffix);
            tempFilePath = file.getCanonicalPath();
            System.out.println("临时文件位置：" + tempFilePath);
            FileOutputStream fstream = new FileOutputStream(file);
            stream = new BufferedOutputStream(fstream);
            stream.write(byteFile);
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (stream != null) {
                try {
                    stream.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        return file;
    }

    /**
     * @Function: 根据地址获得数据的字节流 - GET请求
     * @param  - 网络连接地址
     */
    private static byte[] getImageFromNetByUrl(String strUrl) {
        try {
            URL url = new URL(strUrl);
            HttpURLConnection conn = (HttpURLConnection) url.openConnection();
            conn.setRequestMethod("GET");
            conn.setConnectTimeout(5 * 1000);
            // 通过输入流获取图片数据
            InputStream inStream = conn.getInputStream();
            // 得到图片的二进制数据
            byte[] btImg = readInputStream(inStream);
            return btImg;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * @Function: 从输入流中获取数据
     * @param inStream - 输入流
     * @throws IOException
     */
    private static byte[] readInputStream(InputStream inStream) throws IOException {
        ByteArrayOutputStream outStream = new ByteArrayOutputStream();
        byte[] buffer = new byte[1024];
        int len = 0;
        while ((len = inStream.read(buffer)) != -1) {
            outStream.write(buffer, 0, len);
        }
        inStream.close();
        return outStream.toByteArray();
    }

    /**
     * @Function: 删除临时文件
     */
    public static Boolean deleteFile() {
        boolean flag = false;
        File file = new File(tempFilePath);
        // 路径为文件且不为空则进行删除
        if (file.isFile() && file.exists()) {
            file.delete();
            flag = true;
        }
        return flag;
    }

    /**
     * @Function: base64编码图片转 MultipartFile
     * 注意 转码时 需要把data:image/png;base64,这个前缀给去掉
     */
    public static MultipartFile base64ToMultipart(String base64) {
        if (base64.indexOf(",") > -1) {
            String[] baseStrs = base64.split(",");
            if (null != baseStrs && baseStrs.length > 0) {
                byte[] b = new byte[0];
                b = Base64.decodeFast(baseStrs[1]);
                for (int i = 0; i < b.length; ++i) {
                    // 调整异常数据
                    if (b[i] < 0) {
                        b[i] += 256;
                    }
                }
                return new BASE64DecodedMultipartFile(b, baseStrs[0]);
            }
        }
        return null;
    }

    /**
     * @Function: 将一张网络图片转化成Base64字符串
     * @param imgSrc - 网络图片资源位置
     */
    public static String getImageBase64StrFromUrl(String imgSrc){
        URL url = null;
        InputStream is = null;
        ByteArrayOutputStream outStream = null;
        HttpURLConnection httpUrl = null;

        try{
            url = new URL(imgSrc);
            httpUrl = (HttpURLConnection) url.openConnection();
            httpUrl.setRequestMethod("GET");
            httpUrl.setConnectTimeout(5 * 1000);
            httpUrl.connect();
            httpUrl.getInputStream();
            is = httpUrl.getInputStream();

            outStream = new ByteArrayOutputStream();
            //创建一个Buffer字符串
            byte[] buffer = new byte[1024];
            //每次读取的字符串长度，如果为-1，代表全部读取完毕
            int len = 0;
            //使用一个输入流从buffer里把数据读取出来
            while( (len=is.read(buffer)) != -1 ){
                //用输出流往buffer里写入数据，中间参数代表从哪个位置开始读，len代表读取的长度
                outStream.write(buffer, 0, len);
            }
            // 对字节数组Base64编码
            return java.util.Base64.getEncoder().encodeToString(outStream.toByteArray());
        }catch (Exception e) {
            e.printStackTrace();
        }finally{
            if(is != null) {
                try {is.close(); } catch (IOException e) {e.printStackTrace(); }
            }
            if(outStream != null) {
                try {outStream.close();} catch (IOException e) {e.printStackTrace();}
            }
            if(httpUrl != null){ httpUrl.disconnect();}
        }
        return imgSrc;
    }







    /**
     * @ IOException byte    To    MultipartFile
     */
    public static MultipartFile byteToMultipartFile(byte[] bytes) throws IOException {
        InputStream inputStream = new ByteArrayInputStream(bytes);
        MultipartFile file = new MockMultipartFile(ContentType.APPLICATION_OCTET_STREAM.toString(), inputStream);
        return file;
    }

    /**
     * @ IOException byte    To    MultipartFile
     */
    public static MultipartFile multipartFileToByte(byte[] bytes) throws IOException {
        InputStream inputStream = new ByteArrayInputStream(bytes);
        MultipartFile file = new MockMultipartFile(ContentType.APPLICATION_OCTET_STREAM.toString(), inputStream);
        return file;
    }


    public static byte[] getByteByPic(String imageUrl) throws IOException{
        File imageFile = new File(imageUrl);
        InputStream inStream = new FileInputStream(imageFile);
        BufferedInputStream bis = new BufferedInputStream(inStream);
        BufferedImage bm = ImageIO.read(bis);
        ByteArrayOutputStream bos = new ByteArrayOutputStream();
        String type = imageUrl.substring(imageUrl.length() - 3);
        ImageIO.write(bm, type, bos);
        bos.flush();
        byte[] data = bos.toByteArray();
        return data;
    }
    /**
     * 将图片压缩到指定大小以内
     *
     * @param srcImgData 源图片数据
     * @param maxSize 目的图片大小
     * @return 压缩后的图片数据
     */
    public static byte[] compressUnderSize(byte[] srcImgData, long maxSize) {
        double scale = 0.9;
        byte[] imgData = Arrays.copyOf(srcImgData, srcImgData.length);

        if (imgData.length > maxSize) {
            do {
                try {
                    imgData = compress(imgData, scale);

                } catch (IOException e) {
                    throw new IllegalStateException("压缩图片过程中出错，请及时联系管理员！", e);
                }

            } while (imgData.length > maxSize);
        }

        return imgData;
    }

    /**
     * 按照 宽高 比例压缩
     *
     * @param
     * @param scale 压缩刻度
     * @param
     * @return 压缩后图片数据
     * @throws IOException 压缩图片过程中出错
     */
    public static byte[] compress(byte[] srcImgData, double scale) throws IOException {
        BufferedImage bi = ImageIO.read(new ByteArrayInputStream(srcImgData));
        int width = (int) (bi.getWidth() * scale); // 源图宽度
        int height = (int) (bi.getHeight() * scale); // 源图高度

        Image image = bi.getScaledInstance(width, height, Image.SCALE_SMOOTH);
        BufferedImage tag = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);

        Graphics g = tag.getGraphics();
        g.setColor(Color.RED);
        g.drawImage(image, 0, 0, null); // 绘制处理后的图
        g.dispose();

        ByteArrayOutputStream bOut = new ByteArrayOutputStream();
        ImageIO.write(tag, "JPEG", bOut);

        return bOut.toByteArray();
    }

    //byte数组到图片
    public static void byte2image(byte[] data,String path){
        if(data.length<3||path.equals("")) return;
        try{
            FileImageOutputStream imageOutput = new FileImageOutputStream(new File(path));
            imageOutput.write(data, 0, data.length);
            imageOutput.close();
            System.out.println("Make Picture success,Please find image in " + path);
        } catch(Exception ex) {
            System.out.println("Exception: " + ex);
            ex.printStackTrace();
        }
    }
}